package com.zwh.se.oop.basic;

/**
 * <pre>
 * oop(Object Oriented Programming)一般指面向对象程序设计。
 *      一种基于面向过程的新的编程思想，顾名思义该思想是站在对象的角度思考问题，我们把多个功能合理的放到不同对象里，强调的是我该让谁来做。
 *      本质是以建立模型体现出来的抽象思维过程和面向对象的方法。模型是用来反映现实世界中事物特征的。
 *      任何一个模型都不可能反映客观事物的一切具体特征，只能对事物特征和变化规律的一种抽象，
 *      且在它所涉及的范围内更普遍、更集中、更深刻地描述客体的特征。通过建立模型而达到的抽象是人们对客体认识的深化。
 * </pre>
 * 抽象:就是把现实世界的事物,提取其公共的特征和行为,也即提取其像的部分,提取到计算机中的过程。
 * <p>
 * 类（class）,是对某一类事物的抽象描述(状态和行为),类是一组具有相同特征和行为的对象的抽象描述（集合）,类是一个群体概念
 * 对象（object）,表示现实生活中该类事物的个体,也称之为实体或实例,对象是类这个群体中的一个唯一的、独立的个体,对象是个体概念
 * 类可以看作是对象的数据类型,所谓实例化就表示根据类这个模板制造出每一个对象。
 * 任何事物存在就有一定的功能，在面向对象中，任何事物都可以看成对象，也就是万物皆对象的概念。
 * <p>
 * 简单来说：
 * 对象：具体的事物，具体的实体，具体的实例，模板下具体的产品
 * 类：对对象向上抽取出像的部分，公共的部分，形成类，类是抽象的，是一个模板
 *
 * <pre>
 * 定义语法格式:
 * public class 类名{
 *      //可编写0到N个成员变量
 *      [修饰符] 数据类型 变量名1;
 *      [修饰符] 数据类型 变量名2;
 *
 *      //可编写0到N个成员方法
 *      [修饰符] 返回值类型 方法名称(参数){
 *            //方法体
 *      }
 * }
 * </pre>
 * 为什么存在面向对象?
 * 对象是数据的载体,开发本质上就是把数据存入计算机中,对象和基本数据类型的区别是什么?
 * 基本数据类型只能存单个数据,即便是数组也只能存多个相同类型的数据,这两种根本不够用,因此
 * 我们需要一种更复杂的数据类型,而且这个复杂的数据类型一定要是自定义的
 * 进而,软件开发就是把现实中数据存储到计算机中,必须把共同的特征和行为抽象到计算机中作为类而存在,类又可以创建对象
 * 软件开发数据的展示时,一定要找对象==>无论你做什么都需要找对象来做==>你眼里只有对象==>面向对象==>面向什么就可以看到什么?
 *
 * @author yexi
 */

public class BasicClass {

    // 成员变量(又叫"字段"),字段是"属性"的一部分,并不完全等同于"属性"(这个概念属于学术上的争议,忽视也没什么问题)
    // 定义语法：[修饰符]  属性类型  属性名 = [默认值] ;
    // 定义在类的内部、方法的外部的变量==>表示类的特征(比如这是一个人所抽象的类,人有着名字和年龄这个特征)
    // TIPS:成员变量默认是有初始值的，不同类型的数据类型有着不同的初始值(初始值参考数组即可)
    //      (它们会有默认值是因为它们属于对象的特征,而既然对象都存在了,那这些特征那肯定是已经有了的,但相对的,对象就必须得初始化了)
    // TIPS:作用域:在所定义的类中都有效(其实单纯就是因为{}比较大点的原因,关键就看{})
    // TIPS:生命周期:存储在堆内存中，随着对象的销毁而销毁
    String name;
    int age;

    //成员方法==>表示类的行为(比如这是说出自己的名字)
    // 定义语法：[修饰符]  方法返回值类型  方法名(形参列表) { 方法体 ; [返回值] }
    public void sayName() {
        System.out.println(name);
    }

    //构造器,也称之为构造方法（Constructor）,作用是接到new的后面,用来创建对象的时候,给对象做初始化操作,只能初始化一次
    // 定义语法：[修饰符] 构造器名称(必须跟类名一样) (){ }
    //下面这种没有任何参数的构造器我们叫做：空参构造器-->空构造器，又叫无参构造器
    //无参构造一般用于对实例进行赋初始值/默认值
    // TIPS:也就是说,构造器的本质作用并不是创建对象,因为实际上在调用构造器之前,这个对象就已经创建好了(说的是底层代码),调用构造器的目的是给属性进行赋值操作的。
    //如果一个类没有显式地定义无参构造方法,jvm默认会给该类分配一个无参构造方法(自动分配的无参构造修饰符与定义的类相同)
    //但如果开发者显式定义了无参/有参构造方法,jvm不再自动分配无参构造
    //好的开发习惯:当定义了有参构造时,一定习惯性地把无参构造给加上,哪怕无参构造什么也不做.
    public BasicClass() {
    }

    //因为一般而言,我们定义空构造器并不会主动进行属性的赋值操作,因此我们一般会做的就是构造器的重载,定义出一个或多有参构造器
    public BasicClass(String n, int age) {
        //局部变量:除了成员变量，其他都是局部变量，具体存在于三个地方：1、方法内 2、方法形参 3、代码块中（一对花括号）
        //虽说是三个地方其实都一个道理
        //局部变量并没有默认值,不先赋值会不让编译
        // TIPS:生命周期:存储在栈内存中，随着当前方法从开始执行到执行完毕后销毁
        this();
        name = n;
        //在此处,我们本意是希望形参的 age 的值可以赋予给成员变量的 age,但是它们却有着相同的变量名
        //那样,这个变量赋值就会根据"就近原则"又赋予给了形参自己
        //这种变量名有歧义的问题,专业叫法是局部变量和成员变量存在二义性
        //而使用this就能很好地解决这个问题,this表示当前对象,使得其访问的是成员变量
        //当调用方法时,用什么对象调用,this就表示什么对象,也即是当前对象
        // (举个例子:比如对象s1调动方法,那么此时的this=s1,如果是s2调用的,此时的this=s2)
        this.age = age;
    }

}
/*
    总结一下局部变量和成员变量的区别：
    1、代码中位置不同
       成员变量：类中方法外定义的变量
       局部变量：方法或代码块中定义的变量
    2、代码的作用范围不同
       成员变量：可应用于类中的任何方法
       局部变量：只在当前某一个方法中的某段代码块中生效
    3、是否有默认值
       成员变量：有
       局部变量：没有
    4、是否要初始化
       成员变量：不需要
       局部变量：一定需要，不然直接使用的时候报错
    5、内存中位置不同
       成员变量：堆内存
       局部变量：栈内存
    6、作用时间不同
       成员变量：当前对象从创建到销毁
       局部变量：当前方法从开始执行到执行完毕
 */